package com.itheima.leetcode.od.b.logicalsimulation;

import java.util.*;
import java.util.stream.Collectors;

/**
 * (A卷,100分)- 异常的打卡记录（Java & JS & Python）
 * <p>
 * 题目描述
 * <p>
 * 考勤记录是分析和考核职工工作时间利用情况的原始依据，也是计算职工工资的原始依据，为了正确地计算职工工资和监督工资基金使用情况，公司决定对员工的手机打卡记录进行异常排查。
 * <p>
 * <p>
 * 如果出现以下两种情况，则认为打卡异常：
 * <p>
 * 实际设备号与注册设备号不一样
 * 或者，同一个员工的两个打卡记录的时间小于60分钟并且打卡距离超过5km。
 * 给定打卡记录的字符串数组clockRecords（每个打卡记录组成为：工号;时间（分钟）;打卡距离（km）;实际设备号;注册设备号），返回其中异常的打卡记录（按输入顺序输出）。
 * <p>
 * 输入描述
 * <p>
 * 第一行输入为N，表示打卡记录数；
 * <p>
 * 之后的N行为打卡记录，每一行为一条打卡记录。
 * <p>
 * 输出描述
 * <p>
 * 输出异常的打卡记录。
 * <p>
 * 备注
 * <p>
 * clockRecords长度 ≤ 1000
 * <p>
 * clockRecords[i] 格式：{id},{time},{distance},{actualDeviceNumber},{registeredDeviceNumber}
 * <p>
 * id由6位数字组成
 * <p>
 * time由整数组成，范围为0~1000
 * <p>
 * distance由整数组成，范围为0~100
 * <p>
 * actualDeviceNumber与registeredDeviceNumber由思维大写字母组成
 * <p>
 * 用例
 * <p>
 * 输入	2
 * <p>
 * 100000,10,1,ABCD,ABCD
 * <p>
 * 100000,50,10,ABCD,ABCD
 * <p>
 * 输出	100000,10,1,ABCD,ABCD;100000,50,10,ABCD,ABCD
 * <p>
 * 说明	第一条记录是异常得，因为第二题记录与它得间隔不超过60分钟，但是打卡距离超过了5km，同理第二条记录也是异常得。
 * <p>
 * 输入	2
 * <p>
 * 100000,10,1,ABCD,ABCD
 * <p>
 * 100001,80,10,ABCE,ABCE
 * <p>
 * 输出	null
 * <p>
 * 说明	无异常打卡记录，所以返回null
 * <p>
 * 输入	2
 * <p>
 * 100000,10,1,ABCD,ABCD
 * <p>
 * 100000,80,10,ABCE,ABCD
 * <p>
 * 输出	100000,80,10,ABCE,ABCD
 * <p>
 * 说明	第二条记录得注册设备号与打卡设备号不一致，所以是异常记录
 */
public class AbnormalClockinRecords {
    public static void main(String[] args) {
        /*Scanner in = new Scanner(System.in);

        // 处理输入
        int n = Integer.parseInt(in.nextLine());
        List<String[]> clockRecords = new ArrayList<>();
        for (int i = 0; i < n; i++) {
            String[] record = in.nextLine().split(",");
            clockRecords.add(record);
        }*/

        int n = 2;
        String input = "100000,10,1,ABCD,ABCD\n100000,50,10,ABCD,ABCD";
        List<String[]> clockRecords = Arrays.stream(input.split("\n"))
                .map(s -> s.split(","))
                .collect(Collectors.toCollection(ArrayList::new));

        System.out.println(getResult(n, clockRecords));
    }

    public static String getResult(int n, List<String[]> clockRecords) {
        // 按员工号存放对应员工的打卡记录
        Map<String, List<String[]>> recordMap = new HashMap<>();
        Set<Integer> result = new HashSet<>();

        // 初始化map时实现异常规则1
        for (int i = 0; i < n; i++) {
            String[] singleRecord = clockRecords.get(i);
            // 添加索引
            String[] newRecord = Arrays.copyOf(singleRecord, singleRecord.length + 1);
            newRecord[singleRecord.length] = String.valueOf(i);
            clockRecords.set(i, newRecord);

            if (!singleRecord[3].equals(singleRecord[4])) {
                result.add(i);
            } else {
                recordMap.computeIfAbsent(singleRecord[0], k -> new ArrayList<>()).add(newRecord);
            }
        }

        // 异常规则2
        for (String key : recordMap.keySet()) {
            List<String[]> records = recordMap.get(key);

            // 用打卡时间来排序
            Collections.sort(records, (a, b) -> Integer.parseInt(a[1]) - Integer.parseInt(b[1]));

            for (int i = 0; i < records.size(); i++) {
                int time1 = Integer.parseInt(records.get(i)[1]);
                int dist1 = Integer.parseInt(records.get(i)[2]);

                for (int j = i + 1; j < records.size(); j++) {
                    int time2 = Integer.parseInt(records.get(j)[1]);
                    int dist2 = Integer.parseInt(records.get(j)[2]);

                    // 如果当前的两次打卡时间超过60分钟，后面的肯定也超过60分钟
                    if (time2 - time1 >= 60) {
                        break;
                    } else {
                        if (Math.abs(dist2 - dist1) > 5) {
                            result.add(Integer.parseInt(records.get(i)[5]));
                            result.add(Integer.parseInt(records.get(j)[5]));
                        }
                    }
                }
            }
        }

        // 输出
        if (result.isEmpty()) {
            return String.valueOf(null);
        } else {

            return result.stream()
                    .sorted((a, b) -> a - b)
                    .map(index -> Arrays.stream(Arrays.copyOf(clockRecords.get(index), clockRecords.get(index).length - 1))
                            .collect(Collectors.joining(",")))
                    .collect(Collectors.joining(";"));
        }
    }
}
